package btree;

import java.io.IOException;

import diskmgr.Page;
import global.PageId;
import global.RID;
import heap.InvalidSlotNumberException;
import heap.Tuple;

public class BTLeafPage extends BTSortedPage {

	public BTLeafPage(int keyType) throws ConstructPageException {
		super(keyType);
		try {
			setType(NodeType.LEAF);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public BTLeafPage(PageId pageno, int keyType) throws ConstructPageException {
		super(pageno, keyType);
		try {
			setType(NodeType.LEAF);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public BTLeafPage(Page page, int keyType) {
		super(page, keyType);
		try {
			setType(NodeType.LEAF);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public RID insertRecord(KeyClass key, RID dataRid) {

		KeyDataEntry dataEntry = new KeyDataEntry(key, dataRid);
		try {
			return super.insertRecord(dataEntry);

		} catch (InsertRecException e) {
			return null;

		}
	}

	public KeyDataEntry getFirst(RID rid) {

		try {
			rid = firstRecord();

			try {
				Tuple p = getRecord(rid);
				byte[] byteArray = p.getTupleByteArray();
				KeyDataEntry dataEntry;
				try {
					dataEntry = BT.getEntryFromBytes(byteArray, 0,
							byteArray.length, keyType, NodeType.LEAF);
					return dataEntry;

				} catch (KeyNotMatchException e) {
					return null;

				} catch (NodeNotMatchException e) {
					return null;

				} catch (ConvertException e) {
					return null;

				}
			} catch (InvalidSlotNumberException e) {
				return null;

			}
		} catch (IOException e) {
			return null;

		}

	}

	public KeyDataEntry getNext(RID rid) {

		try {

			RID next = nextRecord(rid);
			rid = next;
			if (next != null) {
				Tuple p = getRecord(next);

				byte[] byteArray = p.getTupleByteArray();
				KeyDataEntry dataEntry = BT.getEntryFromBytes(byteArray, 0,
						byteArray.length, keyType, NodeType.LEAF);
				return dataEntry;
			} else
				return null;
		} catch (Exception e) {
			return null;
		}

	}

	public KeyDataEntry getCurrent(RID rid) {
		try {
			Tuple p = null;
			try {
				p = getRecord(rid);
			} catch (InvalidSlotNumberException e1) {
			}
			byte[] byteArray = p.getTupleByteArray();
			KeyDataEntry dataEntry = null;
			try {
				dataEntry = BT.getEntryFromBytes(byteArray, 0,
						byteArray.length, keyType, NodeType.LEAF);
				return dataEntry;

			} catch (KeyNotMatchException e) {
				return null;

			} catch (NodeNotMatchException e) {
				return null;

			} catch (ConvertException e) {
				return null;

			}

		} catch (IOException e) {
			return null;
		}
	}

	public boolean delEntry(KeyDataEntry keydata)
			throws InvalidSlotNumberException, KeyNotMatchException,
			NodeNotMatchException, ConvertException, IOException,
			DeleteRecException {
		KeyDataEntry kde;
		RID rid = new RID();
		kde = getFirst(rid);
		KeyClass curkey = kde.key;
		KeyClass input = keydata.key;
		boolean stop = false;
		while (BT.keyCompare(curkey, input) != 0 && !stop) {
			kde = getNext(rid);
			if (kde != null)
				curkey = kde.key;
			else
				stop = true;
		}
		if (stop != true) {
			return deleteSortedRecord(rid);
		} else
			return false;
	}

	public RID findRID(KeyClass key) throws KeyNotMatchException {
		KeyDataEntry kde;
		RID rid = new RID();
		kde = getFirst(rid);
		KeyClass curkey = kde.key;
		boolean stop = false;
		while (BT.keyCompare(curkey, key) != 0 && !stop) {
			kde = getNext(rid);
			if (kde != null)
				curkey = kde.key;
			else
				stop = true;
		}
		if (stop != true)
			return rid;
		else
			return null;

	}

}
